#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "socketclient.h"
#include <qmessagebox.h>

#include <string>

#include <json/json.h>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(this->ui->sendBtn, &QPushButton::clicked, this, &MainWindow::onSendButtonClicked);
    connect(this->ui->editBox, &QLineEdit::returnPressed, this, &MainWindow::onSendButtonClicked);
    connect(this->ui->connBtn, &QPushButton::clicked, this, &MainWindow::onConnectButtonClicked);
    this->network = nullptr;
    this->controller = nullptr;
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::onSendButtonClicked()
{
    this->ui->editBox->setFocus();
    QString msg = this->ui->editBox->text();
    if (msg.isEmpty())
        return;
    QString name = this->ui->nameBox->text();
    if (name.isEmpty())
    {
        this->ui->textEdit->setTextColor(Qt::red);
        this->ui->textEdit->append("Warning: please enter your name...");
        return;
    }
    if (this->network == nullptr)
    {
        this->ui->textEdit->setTextColor(Qt::red);
        this->ui->textEdit->append("Error: Not connected...");
        return;
    }
    this->ui->editBox->clear();
    this->ui->textEdit->setTextColor(Qt::green);
    this->ui->textEdit->append("Me: " + msg);
    CTcpClientPtr* conn = (CTcpClientPtr*)this->controller;
    QByteArray dat = msg.toUtf8();
    std::string send(dat.data(), dat.length());

    QByteArray namea = name.toUtf8();
    if (namea.length() > 12)
    {
        this->ui->textEdit->setTextColor(Qt::red);
        this->ui->textEdit->append("Warning: name too long...");
        return;
    }
    std::string names(namea.data(), namea.length());

    Json::Value* pv = new Json::Value;
    Json::Value& v = *pv;
    v["name"] = names;
    v["msg"] = send;

    Json::StreamWriterBuilder sb;
    sb.settings_["indentation"] = "";
    std::string json_str = Json::writeString(sb, v);

    if (json_str.length() > 1024)
    {
        this->ui->textEdit->setTextColor(Qt::red);
        this->ui->textEdit->append("Warning: name too long...");
        return;
    }

    (*conn)->Send((BYTE*)json_str.c_str(), json_str.length());
}

void MainWindow::onConnectButtonClicked()
{
    if (this->network)
    {
        this->ui->textEdit->setTextColor(Qt::red);
        this->ui->textEdit->append("Warning: Client already connected...");
        return;
    }
    this->ui->textEdit->setTextColor(Qt::yellow);
    this->ui->textEdit->append("connecting...");
    SocketClient* work = new SocketClient;

    CTcpClientPtr* conn = new CTcpClientPtr(work);

    if (!(*conn)->Start("124.220.174.206", 1899))
    {
        this->ui->textEdit->setTextColor(Qt::red);
        this->ui->textEdit->append("connect fail...");
        delete conn;
        delete work;
        return;
    }
    this->network = work;
    this->controller = conn;
    connect(work, &SocketClient::clientPrepared, this, &MainWindow::clientPrepared);
    connect(work, &SocketClient::clientConnected, this, &MainWindow::clientConnected);
    connect(work, &SocketClient::recvMsg, this, &MainWindow::clientRecv);
    connect(work, &SocketClient::clientClosed, this, &MainWindow::clientClosed);
}

void MainWindow::clientRecv(QByteArray msg_)
{
    std::string msg(msg_.data(), msg_.length());
    Json::Value* pv = new Json::Value;
    Json::Reader r;
    r.parse(msg, *pv);
    if (!r.good())
    {
        return;
    }
    Json::Value& v = *pv;
    std::string name = v["name"].asString();
    QString names = QString::fromUtf8(name.c_str(), name.length());
    std::string message = v["msg"].asString();
    QString messages = QString::fromUtf8(message.c_str(), message.length());

    this->ui->textEdit->setTextColor(Qt::black);
    this->ui->textEdit->append(names + ": " + messages);
}

void MainWindow::clientPrepared()
{
    this->ui->textEdit->setTextColor(Qt::yellow);
    this->ui->textEdit->append("client prepared...");
}

void MainWindow::clientConnected()
{
    this->ui->textEdit->setTextColor(Qt::yellow);
    this->ui->textEdit->append("client connected...");
}

void MainWindow::clientClosed()
{
    this->ui->textEdit->setTextColor(Qt::yellow);
    this->ui->textEdit->append("client closed...");
    CTcpClientPtr* con = (CTcpClientPtr*)this->controller;
    (*con)->Stop();
    disconnect((SocketClient*)this->network, &SocketClient::clientPrepared, this, &MainWindow::clientPrepared);
    disconnect((SocketClient*)this->network, &SocketClient::clientConnected, this, &MainWindow::clientConnected);
    disconnect((SocketClient*)this->network, &SocketClient::recvMsg, this, &MainWindow::clientRecv);
    disconnect((SocketClient*)this->network, &SocketClient::clientClosed, this, &MainWindow::clientClosed);
    delete con;
    delete (CTcpClientListener*)this->network;
    this->network = nullptr;
    this->controller = nullptr;
}
